<template>
  <div class="add-location-comp">
    <el-input
      placeholder="经度"
      :value="longitude"
      :disabled="disabled"
      :title="longitude"
      @input="(val) => handleChange('longitude', val)">
    </el-input>
    <el-input
      placeholder="纬度"
      :value="latitude"
      :disabled="disabled"
      :title="latitude"
      @input="(val) => handleChange('latitude', val)">
    </el-input>
    <el-input
      v-if="hasAltitude"
      placeholder="高度"
      :value="altitude"
      :disabled="disabled"
      :title="altitude"
      @input="(val) => handleChange('altitude', val)">
    </el-input>
    <i v-if="!disabled" class="iconfont iconditudingweidian-xuanzhong" @click="handleClick"></i>
    <el-dialog
      custom-class="add-location-dialog"
      append-to-body
      :close-on-click-modal="false"
      :destroy-on-close="true"
      :title="addressDetail ? `定位点：${'    '}${addressDetail}` : '定位点'"
      :visible.sync="innerVisible">
      <div class="map-container">
        <div class="point-text">
          <el-input
            :class="['address-input', searchType === 2 ? 'search' : '']"
            placeholder="请输入区划详细地址"
            v-model="addressSearch"
            @keydown.native.enter="handleSearch">
          </el-input>
          <div>
            <span>经度：</span>
            <el-input
              v-if="searchType === 1"
              :value="lng"
              @input="(val) => handleChange('lng', val, false)">
            </el-input>
            <div class="text" v-else>{{ lng }}</div>
          </div>
          <div>
            <span>纬度：</span>
            <el-input
              v-if="searchType === 1"
              :value="lat"
              @input="(val) => handleChange('lat', val, false)">
            </el-input>
            <div class="text" v-else>{{ lat }}</div>
          </div>
          <el-select
            placeholder="请选择查询方式"
            v-model="searchType">
            <el-option :value="1" label="经纬度查询"></el-option>
            <el-option :value="2" label="地址查询"></el-option>
          </el-select>
          <el-button
            class="success"
            type="primary"
            @click="handleSearch">
            查询
          </el-button>
        </div>
        <e-map
          ref="mapRef"
          :eventFn="eventFn"
          :centerOptions="centerOptions">
        </e-map>
      </div>
      <span class="dialog-footer">
        <el-button type="primary" @click="innerVisible = false">取 消</el-button>
        <el-button class="success" type="primary" @click="hanldeSave">保 存</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import eMap from '@/components/corp/Map';

export default {
  name: 'corpAddLocation',
  components: {
    eMap
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    // 定位信息
    value: {
      type: Object,
      default: null
    },
    disabled: {
      type: Boolean,
      default: false
    },
    hasAltitude: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // 地图弹框显示
      innerVisible: false,
      // 经度
      longitude: '',
      // 纬度
      latitude: '',
      // 高度
      altitude: '',
      // 查询经度
      lng: '',
      // 查询纬度
      lat: '',
      // 位置搜索信息
      searchType: 1,
      addressSearch: '',
      // 位置信息
      addressDetail: '',
      // 地图事件
      eventFn: {
        click: this.mapClick
      }
    };
  },
  computed: {
    // 地图中心点设置
    centerOptions() {
      return {
        zoom: 11,
        longitude: this.longitude,
        latitude: this.latitude
      };
    }
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler: function (data) {
        if (this.$checkType(data) === 'object') {
          this.lng = this.longitude = data.lng;
          this.lat = this.latitude = data.lat;
          if (this.hasAltitude) {
            this.altitude = data.altitude;
          }
        }
      }
    },
    innerVisible(value) {
      if (value) {
        this.lng = this.longitude;
        this.lat = this.latitude;
        setTimeout(this.handleSearch, 500);
        return;
      }
      this.lng = this.lat = '';
      this.addressDetail = this.addressSearch = '';
      this.searchType = 1;
    }
  },
  methods: {
    /**
     * 修改经纬度
     * @param key {String} 字段名
     * @param value {String}
     * @param hasEmit {Boolean} 是否传值
     */
    handleChange(key, value, hasEmit = true) {
      if (this.disabled) return;
      this[key] = value;
      hasEmit && this.handleEmit();
    },
    handleClick() {
      this.innerVisible = true;
    },
    /**
     * 地图点击事件
     */
    mapClick(e) {
      /* eslint-disable */
      this.lng = e.latlng.lng;
      this.lat = e.latlng.lat;
      this.setLocation(e.latlng);
    },
    /**
     * 设置地图位置信息
     * @param option {Object|String} 坐标对象 lng：经度 lat：纬度; (地址信息)
     * @param type {String} 查询类型 latlng: 经纬度， address: 地址查询
     */
    setLocation(option, type = 'latlng') {
      try {
        const map = this.$refs.mapRef.myMap;
        if (!map || !option) return;
        // 创建地址解析器实例
        const geoc = new BMapGL.Geocoder();
        // 清除地图上所有的覆盖物
        map.clearOverlays();
        if (type === 'latlng') {
          // 坐标对象
          const newPoint = new BMapGL.Point(option.lng, option.lat);
          const marker = new BMapGL.Marker(newPoint); // 创建标注
          map.addOverlay(marker); // 将标注添加到地图中
          map.panTo(newPoint);
          // 解析地址
          geoc.getLocation(newPoint, (rs) => {
            const addComp = rs && rs.addressComponents;
            if (this.$checkType(addComp) !== 'object') return;
            const { province, city, district, street, streetNumber } = addComp;
            this.addressDetail = `${province ? `${province}` : ''}
            ${city ? `, ${city}` : ''}${district ? `, ${district}` : ''}
            ${street ? `, ${street}` : ''}${streetNumber ? `, ${streetNumber}` : ''}`;
          });
          return;
        }
        // 地址查询 将地址解析结果显示在地图上，并调整地图视野
        geoc.getPoint(option, (point) => {
          if (point) {
            this.lat = point.lat;
            this.lng = point.lng;
            map.centerAndZoom(point, 11);
            map.addOverlay(new BMapGL.Marker(point, {
              title: option
            }));
            return;
          }
          this.$message.warning('您选择的地址没有解析到结果！');
        })
      } catch (e) {}
    },
    /**
     * 地图搜索事件
     */
    handleSearch() {
      if (this.searchType === 1) {
        // 经纬度查询
        this.lng && this.lat && this.setLocation({
          lng: this.lng,
          lat: this.lat
        });
        return;
      }
      // 地址查询
      if (!this.addressSearch || /^\s+$/.test(this.addressSearch)) {
        this.$message.warning('请输入详细地址！');
        return;
      }
      this.addressDetail = this.addressSearch;
      this.setLocation(this.addressSearch, 'address');
    },
    /**
     * 保存定位
     */
    hanldeSave() {
      if (!this.lng || !this.lat) {
        this.$message.warning('经纬度异常！');
        return;
      }
      this.longitude = this.lng;
      this.latitude = this.lat;
      this.handleEmit();
      this.innerVisible = false;
    },
    /**
     * emit当前值
     */
    handleEmit() {
      const options = {
        lng: this.longitude,
        lat: this.latitude,
      };
      if (this.hasAltitude) {
        options.altitude = this.altitude;
      }
      this.$emit('change', options);
    }
  }
};
</script>

<style scoped lang="scss">
@import '../../assets/styles/dialog';

.add-location-comp {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #fff;
  /deep/ .el-input {
    width: 110px;
  }
  .iconfont:hover {
    cursor: pointer;
    color: $lightBtnBg;
  }
}
.add-location-dialog {
  .map-container {
    width: 100%;
    height: 500px;
    position: relative;
    overflow: hidden;
    .point-text {
      position: absolute;
      top: 0;
      left: 0;
      display: flex;
      height: 40px;
      width: 100%;
      z-index: 6;
      align-items: center;
      background-color: rgba(40, 53, 101, .7);
      .address-input {
        height: 40px;
        position: absolute;
        transform: translateY(-100%);
        opacity: 0;
        transition: all .5s;
        &.search {
          transform: translateY(100%);
          opacity: 1;
        }
      }
      > div {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-right: 5px;
        span {
          width: 50px;
          display: inline-block;
          color: #fff;
          &.address-detail {
            width: 180px;
            display: inline-block;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }
        }
        .text {
          color: #fff;
          padding: 0 5px;
        }
        /deep/ .el-input {
          width: 180px;
          height: 30px;
          input {
            height: 30px;
          }
        }
      }
       > /deep/ .el-button {
        height: 30px;
        position: absolute;
        right: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .el-dropdown-link {
        width: 100px;
      }
      .el-select {
        width: 140px;
        /deep/ .el-input__suffix {
          display: flex;
          align-items: center;
          .el-icon-circle-check {
            display: none;
          }
        }
      }
    }
  }
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    padding-top: 10px;
  }
  .detail-container {
    width: 100%;
    height: 40px;
  }
}
</style>
